#include "Company.h"
#include "Exceptions.h"
#include "Common.h"

using namespace DataStructuresWet1;

int Company::IDCounter = 0;

Company::Company() : cmpEmpBySalary(), Employees(cmpEmpBySalary), id(IDCounter++), SalaryMul(1,1), HighestSalary(0,1), MedianSalary(0,1), ownerID(id) {}

Company::~Company() {}

int Company::GetID() const
{
	ValidateActiveCompany();
	return id;
}
void Company::Hire(Employee& employee)
{
	ValidateActiveCompany();
	Employees.Insert(&employee);
	UpdateHighestSalary();
	UpdateMedianSalary();

}
void Company::Fire(int id)
{
	ValidateActiveCompany();
	Employee temp = Employee(id,0,Rational(0));
	Employees.Remove(temp);
	UpdateHighestSalary();
	UpdateMedianSalary();
}
void Company::UpdateSalary(Rational update)
{
	ValidateActiveCompany();
	SalaryMul = update;
}
Rational Company::GetHisghestSalary() const
{
	ValidateActiveCompany();
	return HighestSalary;
}
Rational Company::GetMedianSalary() const
{
	ValidateActiveCompany();
	return MedianSalary;
}
void Company::Merge(const Company &company)
{
	ValidateActiveCompany();
	if (!company.IsActive())
	{
		throw FailureException(); 
	}
	Employees.Merge(company.GetEmployees());
	UpdateHighestSalary();
	UpdateMedianSalary();
}
const AVLTree<Employee>& Company::GetEmployees() const
{
	ValidateActiveCompany();
	return Employees;
}

bool Company::IsActive() const
{
	return (ownerID == id);
}


void Company::UpdateHighestSalary()
{	
	Employee *emp = Employees.MaxElement();
	HighestSalary = emp->GetBaseSalary() * SalaryMul;
}
void Company::UpdateMedianSalary()
{
	Employee *emp = Employees.MaxElement();
	MedianSalary = emp->GetBaseSalary() * SalaryMul;
}

void Company::ValidateActiveCompany() const
{
	if (!IsActive())
	{
		throw FailureException();
	}
}

bool Company::IsLegalCompanyID(int id)
{
	return IS_IN_RANGE(id,0,IDCounter);
}
bool Company::IsLegalSalaryUpdate(Rational update)
{
	return update > 0;
}


int Company::GetOwnerID() const
{
	return ownerID;
}

Rational Company::GetSalaryUpdate() const
{
	return SalaryMul;
}

